﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace XNA_Game_Framework
{
	internal class ControlManager : List<Control>
	{
		Control parent;

		internal ControlManager(Control parent)
		{
			this.parent = parent;
		}

		internal Border AddBorder(string name, Vector2 position, Vector2 size, Border.Sides sides, Theme.Border border)
		{
			if (ControlNameIsFree(name))
			{
				Border newBorder = new Border(parent, name, position, size, sides, border);
				this.Add(newBorder);
				return newBorder;
			}
			else
			{
				throw new NameException("Control name already exists.");
			}
		}

		internal Button AddButton(string name, Vector2 position, Theme.Button theme, string text)
		{
			if (ControlNameIsFree(name))
			{
				Button newButton = new Button(parent, name, position, text, theme);
				this.Add(newButton);
				return newButton;
			}
			else
			{
				throw new NameException("Control name already exists.");
			}
		}

		internal void AddControl(Control control)
		{
			if (ControlNameIsFree(control.Name))
			{
				this.Add(control);
			}
			else
			{
				throw new NameException("Control name already exists.");
			}
		}

		internal Image AddImage(string name, Vector2 position, Texture2D image)
		{
			if (ControlNameIsFree(name))
			{
				Image newImage = new Image(parent, name, position, image);
				this.Add(newImage);
				return newImage;
			}
			else
			{
				throw new NameException("Control name already exists.");
			}
		}

		internal Label AddLabel(string name, Vector2 position, string text, SpriteFont font)
		{
			if (ControlNameIsFree(name))
			{
				Label newLabel = new Label(parent, name, position, text, font);
				this.Add(newLabel);
				return newLabel;
			}
			else
			{
				throw new NameException("Control name already exists.");
			}
		}

		internal Menu AddMenu(InputHandler inputHandler, string name, Vector2 position, string[] entries, Theme.Menu theme, bool isMainMenu)
		{
			if (ControlNameIsFree(name))
			{
				Menu newMenu = new Menu(parent, inputHandler, name, position, entries, theme, isMainMenu);
				this.Add(newMenu);
				return newMenu;
			}
			else
			{
				throw new NameException("Control name already exists.");
			}
		}

		internal Pointer AddPointer(string name, Vector2 position, int height, Theme.Pointer theme)
		{
			if (ControlNameIsFree(name))
			{
				Pointer newPointer = new Pointer(parent, name, position, height, theme);
				this.Add(newPointer);
				return newPointer;
			}
			else
			{
				throw new NameException("Control name already exists.");
			}
		}

		internal TextBox AddTextBox(InputHandler inputHandler, string name, Vector2 position, int width, Theme.TextBox theme)
		{
			if (ControlNameIsFree(name))
			{
				TextBox newTextBox = new TextBox(parent, inputHandler, name, position, width, theme);
				this.Add(newTextBox);
				return newTextBox;
			}
			else
			{
				throw new NameException("Control name already exists.");
			}
		}

		internal TextBox AddTextBox(InputHandler inputHandler, string name, Vector2 position, Vector2 size, Theme.TextBox theme)
		{
			if (ControlNameIsFree(name))
			{
				TextBox newTextBox = new TextBox(parent, inputHandler, name, position, size, theme);
				this.Add(newTextBox);
				return newTextBox;
			}
			else
			{
				throw new NameException("Control name already exists.");
			}
		}

		internal TileImage AddTileImage(string name, Vector2 position, Texture2D image, Vector2 area)
		{
			if (ControlNameIsFree(name))
			{
				TileImage newTileImage = new TileImage(parent, name, position, image, area);
				this.Add(newTileImage);
				return newTileImage;
			}
			else
			{
				throw new NameException("Control name already exists.");
			}
		}

		internal bool ControlNameIsFree(string controlName)
		{
			return parent.Screen.ControlNameIsFree(controlName);
		}

		internal void Draw(SpriteBatch spriteBatch)
		{
			foreach (Control control in this)
			{
				control.Draw(spriteBatch);
			}
		}

		internal Control GetControl(string controlName)
		{
			foreach (Control control in this)
			{
				if (control.Name == controlName)
				{
					return control;
				}
				if (control.RightClickMenu != null && control.RightClickMenu.Name == controlName)
				{
					return control.RightClickMenu;
				}
			}
			return null;
		}

		internal bool RemoveControl(string name)
		{
			foreach (Control control in this)
			{
				if (name == control.Name)
				{
					this.Remove(control);
					return true;
				}
			}
			return false;
		}
	}
}
